LoadAddOn("LibItemBonus-2.0")
local ibl = LibStub("LibItemBonus-2.0")

local LOCINFO = {
	-- INVTYPE_AMMO = GetInventorySlotInfo"AmmoSlot",
	INVTYPE_HEAD = GetInventorySlotInfo"HeadSlot",
	INVTYPE_NECK = GetInventorySlotInfo"NeckSlot",
	INVTYPE_SHOULDER = GetInventorySlotInfo"ShoulderSlot",
	-- INVTYPE_BODY = GetInventorySlotInfo"ShirtSlot",
	INVTYPE_CHEST = GetInventorySlotInfo"ChestSlot",
	INVTYPE_ROBE = GetInventorySlotInfo"ChestSlot",
	INVTYPE_WAIST = GetInventorySlotInfo"WaistSlot",
	INVTYPE_LEGS = GetInventorySlotInfo"LegsSlot",
	INVTYPE_FEET = GetInventorySlotInfo"FeetSlot",
	INVTYPE_WRIST = GetInventorySlotInfo"WristSlot",
	INVTYPE_HAND = GetInventorySlotInfo"HandsSlot",
	INVTYPE_FINGER = {(GetInventorySlotInfo"Finger0Slot"), (GetInventorySlotInfo"Finger1Slot")},
	INVTYPE_TRINKET = {(GetInventorySlotInfo"Trinket0Slot"), (GetInventorySlotInfo"Trinket1Slot")},
	INVTYPE_CLOAK = GetInventorySlotInfo"BackSlot",
	INVTYPE_WEAPON = {(GetInventorySlotInfo"MainHandSlot"), (GetInventorySlotInfo"SecondaryHandSlot")},
	INVTYPE_SHIELD = GetInventorySlotInfo"SecondaryHandSlot",
	INVTYPE_2HWEAPON = GetInventorySlotInfo"MainHandSlot",
	INVTYPE_WEAPONMAINHAND = GetInventorySlotInfo"MainHandSlot",
	INVTYPE_WEAPONOFFHAND = GetInventorySlotInfo"SecondaryHandSlot",
	INVTYPE_HOLDABLE = GetInventorySlotInfo"SecondaryHandSlot",
	INVTYPE_RANGED = GetInventorySlotInfo"RangedSlot",
	INVTYPE_THROWN = GetInventorySlotInfo"RangedSlot",
	INVTYPE_RANGEDRIGHT = GetInventorySlotInfo"RangedSlot",
	INVTYPE_RELIC = GetInventorySlotInfo"RangedSlot",
--	INVTYPE_TABARD = GetInventorySlotInfo"TabardSlot",
--	INVTYPE_BAG = {(GetInventorySlotInfo"Bag0Slot"), (GetInventorySlotInfo"Bag1Slot"), (GetInventorySlotInfo"Bag2Slot"), (GetInventorySlotInfo"Bag3Slot")},
--	INVTYPE_QUIVER = {(GetInventorySlotInfo"Bag0Slot"), (GetInventorySlotInfo"Bag1Slot"), (GetInventorySlotInfo"Bag2Slot"), (GetInventorySlotInfo"Bag3Slot")},
}

local LOCEQ = {
	INVTYPE_RANGED = "INVTYPE_RANGED",
	INVTYPE_THROWN = "INVTYPE_RANGED",
	INVTYPE_RANGEDRIGHT = "INVTYPE_RANGED",
	INVTYPE_CHEST = "INVTYPE_CHEST",
	INVTYPE_ROBE = "INVTYPE_CHEST",
	INVTYPE_WEAPONOFFHAND = "INVTYPE_WEAPONOFFHAND",
	INVTYPE_HOLDABLE = "INVTYPE_WEAPONOFFHAND",
	INVTYPE_SHIELD = "INVTYPE_WEAPONOFFHAND",
	INVTYPE_WEAPONMAINHAND = "INVTYPE_WEAPONMAINHAND",
	INVTYPE_2HWEAPON = "INVTYPE_WEAPONMAINHAND",
}

local POW_FACTOR = (math.log(2)/math.log(1.5))
local INV_POW_FACTOR = 1 / POW_FACTOR
local STAT_VALUE = {
	ATTACKPOWER = 0.5,

	BLOCKVALUE = 0.65,

	STA = 2/3,
	STR = 1,
	AGI = 1,
	SPI = 1,
	INT = 1,

	DMG = 6/7,

	SPELLPEN = 1,
	MANAREG = 2.5,
	ARCANERES = 1,
	NATURERES = 1,
	SHADOWRES = 1,
	FIRERES = 1,
	FROSTRES = 1,

	CR_WEAPON = 1,
	CR_DEFENSE = 1,
	CR_DODGE = 1,
	CR_PARRY = 1,
	CR_BLOCK = 1,
	CR_HIT = 1,
	CR_CRIT = 1,
	CR_HASTE = 1,
	CR_SPELLHIT = 1,
	CR_SPELLCRIT = 1,
	CR_SPELLHASTE = 1,
	CR_RESILIENCE = 1,
	CR_WEAPON_AXE = 1,
	CR_WEAPON_DAGGER = 1,
	CR_WEAPON_MACE = 1,
	CR_WEAPON_SWORD = 1,
	CR_WEAPON_SWORD_2H = 1,
	CR_EXPERTISE = 1,

	EMPTY_SOCKET_BLUE = 10,
	EMPTY_SOCKET_RED = 10,
	EMPTY_SOCKET_YELLOW = 10,
	EMPTY_SOCKET_META = 15,
}

local LOCMULT = {
	INVTYPE_CHEST = 1,
	INVTYPE_ROBE = 1,
	INVTYPE_HEAD = 1,
	INVTYPE_LEGS = 1,
	INVTYPE_2HWEAPON = 1,
	INVTYPE_SHOULDER = 4/3,
	INVTYPE_HAND = 4/3,
	INVTYPE_WAIST = 4/3,
	INVTYPE_FEET = 4/3,
	INVTYPE_WRIST = 16/9,
	INVTYPE_NECK = 16/9,
	INVTYPE_CLOAK = 16/9,
	INVTYPE_FINGER = 16/9,
	INVTYPE_WEAPONOFFHAND = 16/9,
	INVTYPE_HOLDABLE = 16/9,
	INVTYPE_SHIELD = 16/9,
	INVTYPE_TRINKET = 32/25,
	INVTYPE_WEAPON = 64/27,
	INVTYPE_WEAPONMAINHAND = 64/27,
	INVTYPE_RANGED = 256/81,
	INVTYPE_THROWN = 256/81,
	INVTYPE_RANGEDRIGHT = 256/81,
	INVTYPE_RELIC = 256/81,
}

local BONUS_BLACKLIST = {
	WEAPON_MIN = true,
	WEAPON_SPEED = true,
}

local Summary = {}

local function clean_item_link(link)
	local itemid, suffixId = link:match("item:([^:]+):[^:]+:[^:]+:[^:]+:[^:]+:[^:]+:([^:]+:[^:]+)")
	return "item:"..itemid..":0:0:0:0:0:"..suffixId
end

do
	local hook_otsi = function (...) Summary:OnTooltipSetItem(...) end
	local hook_otc = function (...) Summary:OnTooltipCleared(...) end
	function Summary:HookTooltip(tt)
		tt:HookScript("OnTooltipSetItem", hook_otsi)
		tt:HookScript("OnTooltipCleared", hook_otc)
	end
end

function Summary:OnTooltipSetItem(tt)
	if not tt.summary_set and self:AddSummary(tt) then
		tt.summary_set = true
	end
end

function Summary:OnTooltipCleared(tt)
	tt.summary_set = nil
end

local function addtostats(stats, bonus)
	for b in pairs(bonus) do
		if not BONUS_BLACKLIST[b] then
			local found
			for _, v in ipairs(stats) do
				if v == b then found = true break end
			end
			if not found then
				stats[#stats + 1] = b
			end
		end
	end
end

local function delta(a, b, fmt)
	local v = (a or 0) - (b or 0)
	if v == 0 then return end
	local color, sign
	if v < 0 then
		color, sign, v = RED_FONT_COLOR_CODE, "-", -v
	else
		color, sign = GREEN_FONT_COLOR_CODE, "+"
	end
	return color .. sign .. (fmt or "%d"):format(v) .. FONT_COLOR_CODE_CLOSE
end

local function concat(a, b)
	if not a and not b then return end
	return (a or "0") .. " / " .. (b or "0")
end

local function get_stat_multiplier(stat)
	local s = STAT_VALUE[stat]
	if s then return s end
	if stat == EMPTY_SOCKET_BLUE or stat == EMPTY_SOCKET_RED or stat == EMPTY_SOCKET_YELLOW then
		local level =
end

local function get_item_value(info)
	local sum = 0
	for i, stat in ipairs(stats) do
		local mult = STAT_VALUE[stat]
		if mult then
			sum = sum + math.pow(mult * (info.bonuses[stat] or 0), POW_FACTOR)
		end
	end
	return math.pow(sum, INV_POW_FACTOR)
end

local function add_value_comparison(tt, info, infoa, infob, slotModifier)
	local base = get_item_value(info) * slotModifier
	local left =  ("Item value: %.1f"):format(base)
	local v = delta(base, get_item_value(infoa) * slotModifier, "%.1f")
	if infob then
		v = concat(v, delta(base, get_item_value(infob) * slotModifier, "%.1f"))
	end
	if v then
		tt:AddDoubleLine(left, v, 0.4, 0.2, 0.9, 1, 1, 1)
	else
		tt:AddLine(left, 0.4, 0.2, 0.9)
	end
end

local function get_slot_info(slot, loc)
	local ilink = GetInventoryItemLink("player", slot)
	if not ilink then return end
	local iloc = select(9, GetItemInfo(ilink))
	if loc ~= iloc and LOCEQ[loc] and LOCEQ[loc] ~= LOCEQ[iloc] then return end
	return ibl:ScanItemLink(clean_item_link(ilink))
end

function Summary:AddSummary(tt)
	local _, link = tt:GetItem()
	if not link then return end
	local loc = select(9, GetItemInfo(link))
	if not loc then return end
	local slots = LOCINFO[loc]
	if not slots then return end
	local infoa, infob
	if type(slots) == "number" then
		infoa = get_slot_info(slots, loc)
	else
		infoa = get_slot_info(slots[1], loc)
		infob = get_slot_info(slots[2], loc)
		if not infoa then
			infoa, infob = infob, infoa
		end
	end
	if not infoa then return end

	local info = ibl:ScanItemLink(clean_item_link(link))
	addtostats(stats, info.bonuses)
	addtostats(stats, infoa.bonuses)
	if infob then addtostats(stats, infob.bonuses) end

	add_value_comparison(tt, info, infoa, infob, LOCMULT[loc])
	for i in ipairs(stats) do stats[i] = nil end
end

Summary:HookTooltip(GameTooltip)
Summary:HookTooltip(ItemRefTooltip)
Summary:HookTooltip(ShoppingTooltip1)
Summary:HookTooltip(ShoppingTooltip2)

_G.Summary = Summary
